package fr.utt.lo02.CrazyEights.view;


import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

import fr.utt.lo02.CrazyEights.model.cards.Card;
import fr.utt.lo02.CrazyEights.model.players.Human;
import fr.utt.lo02.CrazyEights.model.players.Player;
import fr.utt.lo02.CrazyEights.model.players.PlayersList;



/**
 * A panel which represents a player
 * @author Jeremy
 *
 */
public class PlayerPanel extends JPanel implements Observer{
	private static final long serialVersionUID = 1L;
	private Player player;
	private PlayersList playersList;
	private ArrayList<ImageLabel> cards = new ArrayList<ImageLabel>();
	private JLabel playerName;
	private JLabel nbCardsInHand;
	private GridBagConstraints gbc;
	private int firstCardToShow = 0;
	private int lastCardToShow = 7;
	private JButton nextCard;
	private JButton previousCard;
	
	/**
	 * Create the panel for the given player
	 * @param p the player for which we create the panel
	 * @param pl the players list
	 */
	public PlayerPanel(Player p, PlayersList pl){
		player = p;
		playersList = pl;
		p.addObserver(this);
		pl.addObserver(this);
		this.setLayout(new GridBagLayout());
		playerName = new JLabel(player.getName());
		nbCardsInHand = new JLabel();
		nextCard = new JButton("Next");
		previousCard = new JButton("Previous");
		
		nextCard.addActionListener(new NextCardState());
		previousCard.addActionListener(new PreviousCardState());
		
		playerName.setForeground(Color.white);
		nbCardsInHand.setForeground(Color.white);
		gbc = new GridBagConstraints();
		updateCardsInHand();
	}
	
	/**
	 * Refresh the display of cards in hand
	 */
	public void updateCardsInHand(){
		
		this.setVisible(false);
		this.removeAll();
		cards.clear();
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridwidth = 1;
		gbc.gridy = 1;
		
		if(player==playersList.getCurrentPlayer() && (player instanceof Human)){
			
			gbc.insets = new Insets(0,0,0,0);
			this.add(previousCard,gbc);
			
			if(lastCardToShow-firstCardToShow+1<8 && player.getNbCardsInHand()>0){
				if(firstCardToShow>0){
					firstCardToShow--;
				}else{
					lastCardToShow = 7;
				}
			}
			
			if(firstCardToShow>0){
				previousCard.setEnabled(true);
			}
			else{
				previousCard.setEnabled(false);
			}
			gbc.insets = new Insets(0,5,0,5);
			
			if(player.getNbCardsInHand()-1<=lastCardToShow){
				lastCardToShow = player.getNbCardsInHand()-1;
			}
			
			for(int i= firstCardToShow;i<=lastCardToShow;i++){
				cards.add(new ImageLabel(player.getCardsInHand().get(i)));
				cards.get(cards.size()-1).setPreferredSize(new Dimension(MainWindow.cardWidth, MainWindow.cardHeight));
				this.add(cards.get(cards.size()-1),gbc);
			}
			
			for(ImageLabel il : cards){
				il.addMouseListener(new CardState(il.getCard()));
			}
			
			gbc.insets = new Insets(0,0,0,0);
			this.add(nextCard,gbc);
			
			if(player.getNbCardsInHand()-1>lastCardToShow){
				nextCard.setEnabled(true);
			}else{
				nextCard.setEnabled(false);
			}
		}
		else{
			gbc.insets = new Insets(0,5,0,5);
			if(player.getNbCardsInHand()>0){
				cards.add(new ImageLabel());
				cards.get(0).setPreferredSize(new Dimension(MainWindow.cardWidth, MainWindow.cardHeight));
				this.add(cards.get(0),gbc);
			}
		}
		
		gbc.gridy = 0;
		if(player==playersList.getCurrentPlayer()){
			gbc.gridwidth = lastCardToShow-firstCardToShow+3;
		}else{
			gbc.gridwidth = 1;
		}
		this.add(playerName,gbc);
		gbc.gridy = 2;
		nbCardsInHand.setText(player.getNbCardsInHand()+" remaining cards");
		this.add(nbCardsInHand,gbc);
		
		this.setVisible(true);
	}
	
	/**
	 * MouseAdapter for cards to know which card was clicked
	 * @author Jeremy
	 *
	 */
	class CardState extends MouseAdapter{
		private Card card;
		
		public CardState(Card card){
			this.card = card;
		}
		
		public void mouseClicked(MouseEvent e){
			if(playersList.getCurrentPlayer()==player){
				player.play(card);
			}
		}
	}
	
	/**
	 * ActionListener for the next button
	 * @author Jeremy
	 *
	 */
	class NextCardState implements ActionListener{
		public void actionPerformed(ActionEvent arg0) {
			firstCardToShow++;
			lastCardToShow++;
			updateCardsInHand();
		}
	}
	
	/**
	 * ActionListner for the previous button
	 * @author Jeremy
	 *
	 */
	class PreviousCardState implements ActionListener{
		public void actionPerformed(ActionEvent arg0) {
			firstCardToShow--;
			lastCardToShow--;
			updateCardsInHand();
		}
	}
	
	public void update(Observable o, Object arg){
		updateCardsInHand();
	}
}
